"""
无人机类模块 - 实现无人机的基本属性和方法
"""

import numpy as np
import time
from enum import Enum
import config

class UAVState(Enum):
    """无人机状态枚举"""
    IDLE = 0          # 空闲
    FLYING = 1        # 飞行中
    COMMUNICATING = 2 # 通信中
    LOW_BATTERY = 3   # 低电量
    EMERGENCY = 4     # 紧急状态

class UAV:
    """无人机类"""
    
    def __init__(self, uav_id, initial_position=None):
        """
        初始化无人机实例
        
        参数:
            uav_id: 无人机ID
            initial_position: 初始位置，默认为随机位置
        """
        self.id = uav_id
        
        # 如果没有指定初始位置，则随机生成
        if initial_position is None:
            self.position = np.random.rand(3) * config.AREA_SIZE
        else:
            self.position = np.array(initial_position)
            
        # 随机生成速度方向，速度大小固定
        direction = np.random.rand(3) - 0.5
        self.velocity = direction / np.linalg.norm(direction) * config.UAV_SPEED
        
        # 初始化其他属性
        self.state = UAVState.IDLE
        self.battery = config.BATTERY_CAPACITY
        self.message_queue = []  # 待发送消息队列
        self.received_messages = []  # 接收到的消息
        self.neighbors = set()  # 邻居无人机集合
        self.communication_history = []  # 通信历史
        self.creation_time = time.time()  # 创建时间
        
        # 链路质量记录
        self.link_quality = {}  # 记录与其他无人机的链路质量
        
        # 性能统计
        self.stats = {
            'sent_packets': 0,
            'received_packets': 0,
            'lost_packets': 0,
            'avg_delay': 0,
            'total_delay': 0,
            'emergency_packets_handled': 0,
            'retransmissions': 0
        }
    
    def update_position(self, time_step):
        """
        更新无人机位置
        
        参数:
            time_step: 时间步长
        """
        # 简单边界处理 - 碰到边界反弹
        for i in range(3):
            if self.position[i] <= 0 or self.position[i] >= config.AREA_SIZE:
                self.velocity[i] = -self.velocity[i]
                
        # 更新位置
        self.position += self.velocity * time_step
        
        # 随机微调方向 (增加一些随机性)
        if np.random.random() < 0.05:  # 5%概率改变方向
            direction_change = (np.random.rand(3) - 0.5) * 0.2
            self.velocity += direction_change
            # 保持速度大小不变
            self.velocity = self.velocity / np.linalg.norm(self.velocity) * config.UAV_SPEED
        
        # 更新电池状态
        self.battery -= config.POWER_CONSUMPTION_RATE * time_step / 60  # 转换为分钟
        
        # 如果电池电量低，更新状态
        if self.battery < 0.2 * config.BATTERY_CAPACITY:
            self.state = UAVState.LOW_BATTERY
        
    def distance_to(self, other_uav):
        """
        计算与另一架无人机的距离
        
        参数:
            other_uav: 另一架无人机实例
            
        返回:
            距离值(米)
        """
        return np.linalg.norm(self.position - other_uav.position)
    
    def can_communicate_with(self, other_uav):
        """
        判断是否能与另一架无人机通信
        
        参数:
            other_uav: 另一架无人机实例
            
        返回:
            布尔值，表示是否能通信
        """
        return self.distance_to(other_uav) <= config.UAV_COMM_RANGE
    
    def update_neighbors(self, uav_list):
        """
        更新邻居列表
        
        参数:
            uav_list: 所有无人机列表
        """
        self.neighbors.clear()
        for uav in uav_list:
            if uav.id != self.id and self.can_communicate_with(uav):
                self.neighbors.add(uav.id)
                
                # 更新链路质量 (根据距离计算)
                distance = self.distance_to(uav)
                quality = max(0, 1 - distance / config.UAV_COMM_RANGE)
                self.link_quality[uav.id] = quality
    
    def add_message_to_queue(self, message):
        """
        添加消息到发送队列
        
        参数:
            message: 待发送的消息
        """
        self.message_queue.append(message)
        # 根据优先级排序队列
        self.message_queue.sort(key=lambda x: x.priority)
    
    def process_received_message(self, message):
        """
        处理接收到的消息
        
        参数:
            message: 接收到的消息
        """
        self.received_messages.append(message)
        self.stats['received_packets'] += 1
        
        # 计算时延
        delay = time.time() - message.creation_time
        self.stats['total_delay'] += delay
        self.stats['avg_delay'] = self.stats['total_delay'] / self.stats['received_packets']
        
        # 如果是紧急消息，更新紧急消息处理计数
        if message.type == 'EMERGENCY':
            self.stats['emergency_packets_handled'] += 1
    
    def get_status_summary(self):
        """
        获取无人机状态摘要
        
        返回:
            状态摘要字典
        """
        return {
            'id': self.id,
            'position': self.position,
            'velocity': self.velocity,
            'state': self.state,
            'battery': self.battery,
            'neighbors': list(self.neighbors),  # 返回邻居ID列表而不是数量
            'queue_size': len(self.message_queue),
            'stats': self.stats
        }
    
    def __str__(self):
        """字符串表示"""
        return f"UAV-{self.id} at {self.position} state: {self.state.name}" 